#include <QUndoStack>
#include "Qt3DPicker.h"
#include "CmdManager.h"
#include "MultiSectionCylinderHandler.h"
#include "MultiSectionCylinder.h"
#include "Operation/OpAdd.h"
#include "PointHandler.h"
#include "SendPointHandlerBase.h"
#include "Scene.h"
#include "QtOSGWidget.h"
#include "SelectHandler3D.h"
#include "Ucs.h"


MultiSectionCylinderHandler::MultiSectionCylinderHandler()
{
}

MultiSectionCylinderHandler::~MultiSectionCylinderHandler()
{
	if (m_cylinders)
	{
		auto widget = getWidget();
		auto scene = getScene();
		widget->pauseRenderThread();
		scene->removeChild(m_cylinders);
		widget->resumeRenderThread();
	}
}

void MultiSectionCylinderHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	auto sph = getSendPointHandler();
	auto scene = getScene();
	auto widget = getWidget();
	if (data.type() == QVariant::Bool && !data.toBool())
	{
		emit finished();
		return;
	}

	if (status() == 0)
	{
		m_cylinders = std::make_shared<MultiSectionCylinder>(scene);
		widget->pauseRenderThread();
		scene->addChild(m_cylinders);
		widget->resumeRenderThread();
		if (sph)
		{
			sph->setPointMask(CS_LBTNDOWN);
		}
		prompt(1, tr("基准点: "));
		return;
	}

	if (status() == 1)
	{
		if (data.type() == QVariant::Vector3D)
		{
			auto pt = data.value<QVector3D>();
			m_point = {pt.x(),pt.y(),pt.z()};
			m_cylinders->setBottomCenter(m_point);
			enableMouseHandler(MouseHandlerID::Manipulator);
			prompt(5, tr("指定轴向[两点(0)/方向向量(1)]<0,0,1>:"));
		}
		return;
	}

	if (status() == 5)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_axis.set(0, 0, 1);
			if (sph)
			{
				sph->setPointMask(CS_CMDLINE);
			}
			prompt(2, tr("圆台高:"));
			return;
		}
		if (data.type() == QVariant::Double)
		{
			if (data.toInt() == 0)
			{
				if (sph)
				{
					sph->setPointMask(CS_LBTNDOWN);
				}
				enableMouseHandler(MouseHandlerID::PointSender);
				prompt(6, tr("指定起点: "));
			}
			else if (data.toInt() == 1)
			{
				if (sph)
				{
					sph->setPointMask(CS_CMDLINE);
				}
				prompt(8, tr("指定轴向向量: "));
			}
			return;
		}
		return;
	}

	if (status() == 6)
	{
		if (data.type() == QVariant::Vector3D)
		{
			auto pt = data.value<QVector3D>();
			m_start = { pt.x(),pt.y(),pt.z() };
			prompt(7, tr("指定终点: "));
		}
		return;
	}

	if (status() == 7)
	{
		if (data.type() == QVariant::Vector3D)
		{
			auto pt = data.value<QVector3D>();
			m_end = { pt.x(),pt.y(),pt.z() };
			m_axis = m_end - m_start;
			double len = m_axis.normalize();
			if (len == 0)
			{
				remark(tr("起点终点重合，无法指明轴向"));
				return;
			}
			m_cylinders->setAxis(m_axis);
			if (sph)
			{
				sph->setPointMask(CS_CMDLINE);
			}
			prompt(2, tr("圆台高:"));
		}
		return;
	}

	if (status() == 8)
	{
		if (data.type() == QVariant::Vector3D)
		{
			auto pt = data.value<QVector3D>();
			m_axis = { pt.x(),pt.y(),pt.z() };
			double len = m_axis.normalize();
			if (len == 0)
			{
				remark(tr("轴向向量不可以是0向量"));
				return;
			}
			m_cylinders->setAxis(m_axis);
			if (sph)
			{
				sph->setPointMask(CS_CMDLINE);
			}
			prompt(2, tr("圆台高:"));
		}
		return;
	}

	if (status() == 2)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			if (m_cylinders->sectionCount()>0)
			{
				auto undoStack = scene->undoStack();
				undoStack->push(new OpAdd(m_cylinders->decompose()));
			}
			emit finished();
			return;
		}
		else if (data.type() == QVariant::Double)
		{
			m_height = data.toFloat();
			if (m_height <= 0)
			{
				remark(tr("圆台高必须大于0"));
				emit finished();
				return;
			}
			if (m_topDiameter >= 0)
			{
				prompt(3, tr("圆台下部直径<%1>:").arg(m_topDiameter));
			}
			else
			{
				prompt(3, tr("圆台下部直径:"));
			}
		}
		return;
	}

	if (status() == 3)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_bottomDiameter = m_topDiameter;
		}
		else if (data.type() == QVariant::Double)
		{
			m_bottomDiameter = data.toFloat();
			if (m_bottomDiameter < 0)
			{
				remark(tr("圆台下部直径必须 >= 0"));
				emit finished();
				return;
			}
		}
		prompt(4, tr("圆台上部直径<%1>:").arg(m_bottomDiameter));
		return;
	}

	if (status() == 4)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_topDiameter = m_bottomDiameter;
		}
		else if (data.type() == QVariant::Double)
		{
			m_topDiameter = data.toFloat();
		}
		if (m_topDiameter < 0)
		{
			remark(tr("圆台上部直径必须 >= 0"));
			emit finished();
			return;
		}
		if (m_bottomDiameter==0 && m_topDiameter==0)
		{
			remark(tr("圆台两个直径不能同时为0"));
			return;
		}
		widget->pauseRenderThread();
		m_cylinders->addSection(m_bottomDiameter / 2.0, m_topDiameter / 2.0, m_height);
		widget->resumeRenderThread();
		prompt(2, tr("圆台高<结束>:"));
		return;
	}
}


